package com.statapp;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.achartengine.ChartFactory;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.TimeSeries;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.util.Log;
import android.widget.Toast;

/** 
 * This class represents a line chart to visualize sales volume data.
 * 
 * @author Peter Goldenbogen (Munich University of Applied Science)
 * @version 1.0 
 */  

public class SalesVolume {
	
	private final String url = "http://"+ StatAppActivity.server_address + "/ChartService/rest/kpi/get_sales_volume";
	private String title = "Chart Title";
	private String identifier = "id";
	private String seriesTitle = "series1";
	private String dataPeriodStart;
	private String dataPeriodEnd;
	private ArrayList<String> axisTitles = new ArrayList<String>(2);
	
	private int[] y = new int[100];
	private Date[] x = new Date[100];
	
	/**
	 * Sets up a TimeChartIntent with rendering parameters and data sets to display product share data
	 * @param context The application context
	 * @return An Intent which will start an activity to display a line chart visualizing the XML data
	 * @see TimeChartIntent
	 */
	public Intent getIntent(Context context){
		
		String xmlData = this.getSalesVolumeData();
		
		if(xmlData != null){
			this.parseXml(xmlData);		
		}
		else{
			Toast.makeText(context, "No data available!", Toast.LENGTH_SHORT).show();
			return new Intent(context, StatAppActivity.class);
		}
		
		TimeSeries tSeries = new TimeSeries(seriesTitle + " (last value: " + dataPeriodEnd + ")");
		
		for(int i = 0; i < y.length; i++){
			tSeries.add(x[i], y[i]);
		}
		
		XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
		dataset.addSeries(tSeries);
		
		XYSeriesRenderer renderer = new XYSeriesRenderer();
		renderer.setColor(Color.WHITE);
		renderer.setPointStyle(PointStyle.SQUARE);
		renderer.setFillPoints(true);
		
		XYMultipleSeriesRenderer mRenderer = new XYMultipleSeriesRenderer();
		mRenderer.setChartTitle(title);
		mRenderer.setYAxisMin(0);
		mRenderer.addSeriesRenderer(renderer);
		mRenderer.setChartTitleTextSize(25);
		mRenderer.setZoomButtonsVisible(true);
		mRenderer.setLabelsTextSize(20);
		mRenderer.setXTitle(axisTitles.get(0));
		mRenderer.setYTitle(axisTitles.get(1));
		
		Intent intent = ChartFactory.getTimeChartIntent(context, dataset, mRenderer, title);
		return intent;
	}
	
	/**
	 * Fetches Data from a XML based REST WS (GET)
	 * @param context The application context
	 * @return a String holding all XML data returned by the server
	 */
	public void parseXml(String xml){
		
		Document dom = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		
		DocumentBuilder db;
		try
		{
			db = dbf.newDocumentBuilder();
			InputSource is = new InputSource();
			is.setCharacterStream(new StringReader(xml));
			dom = db.parse(is);
			Element root = dom.getDocumentElement();
			NodeList rootNl = root.getChildNodes();
			//keyIndicator
			for(int i = 0; i < rootNl.getLength(); i++){
				
				Node rootNode = rootNl.item(i);
				
				if(rootNode.getNodeName().equalsIgnoreCase("title"))
					title = rootNode.getChildNodes().item(0).getNodeValue();
				
				else if (rootNode.getNodeName().equalsIgnoreCase("identifier"))
					identifier = rootNode.getChildNodes().item(0).getNodeValue();
				
				else if (rootNode.getNodeName().equalsIgnoreCase("dataPeriodEnd")){
					Log.d("statapp",rootNode.getChildNodes().item(0).getNodeValue());
					dataPeriodEnd = rootNode.getChildNodes().item(0).getNodeValue().substring(0, 19);
				}
				
				else if (rootNode.getNodeName().equalsIgnoreCase("dataPeriodStart")){
					Log.d("statapp",rootNode.getChildNodes().item(0).getNodeValue());
					dataPeriodStart = rootNode.getChildNodes().item(0).getNodeValue().substring(0, 19);
				}
				
				else if (rootNode.getNodeName().equalsIgnoreCase("lineChart")){
					
					NodeList lineChartNl = rootNode.getChildNodes();
					//lineChart
					for(int j = 0; j < lineChartNl.getLength(); j++){
						
						Node lineChartNode = lineChartNl.item(j);
						
						if(lineChartNode.getNodeName().equalsIgnoreCase("axis")){
							
							axisTitles.add(lineChartNode.getAttributes().getNamedItem("title").getNodeValue());
						}
						
						else if(lineChartNode.getNodeName().equalsIgnoreCase("lineValueSeries")){
							
							NodeList lineVsNl = lineChartNode.getChildNodes();
							seriesTitle = lineChartNode.getAttributes().getNamedItem("title").getNodeValue();
							
							//LineValueSeries
							for(int k = 0; k < lineVsNl.getLength(); k++){
								
								Node lineVsNode = lineVsNl.item(k);
								NodeList pointNl = lineVsNode.getChildNodes();
								
								//point
								for(int l = 0; l < pointNl.getLength(); l++){
									
									Node pointNode = pointNl.item(l);
									
									if(pointNode.getNodeName().equalsIgnoreCase("xValue")){
										x[k] = new Date(Long.parseLong(pointNode.getChildNodes().item(0).getNodeValue()));
									}
									else if(pointNode.getNodeName().equalsIgnoreCase("yValue") && pointNl.getLength() > 1){
										y[k] = Integer.parseInt(pointNode.getChildNodes().item(0).getNodeValue());
										
									}
								}
							}
						}
					}
				}
			}
		} 
		catch (ParserConfigurationException e) {
			Log.e("statapp", e.getMessage());
		} catch (SAXException e) {
			Log.e("statapp", e.getMessage());
		} catch (IOException e) {
			Log.e("statapp", e.getMessage());
		}
		
	}

	/**
	 * Parses the XML data an updates class variables
	 * @param the String that will be searched for XML data to feed the pie chart
	 */
	public String getSalesVolumeData(){
		
		HttpClient httpClient = new DefaultHttpClient();
		HttpGet request = new HttpGet(url);
		ResponseHandler<String> handler = new BasicResponseHandler();
		String result = null;
		
		try {
			result = httpClient.execute(request, handler);
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		httpClient.getConnectionManager().shutdown();
		Log.v("statapp", "get_product_share called! Result:" + result);
		
		return result;
	}
}
